package com.hw.common.utils;

import jodd.bean.BeanCopy;
import jodd.bean.BeanUtil;
import org.apache.commons.collections.BeanMap;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/*****
 * <pre>
 * 类名称：BeanTools
 * 类描述：BEAN操作工具类
 * 创建人：JokenWang
 * 创建时间：2014年12月16日 上午8:59:51
 * </pre>
 * 
 * @version 1.0.0
 */
@SuppressWarnings("deprecation")
public final class BeanUtils
{
    private static Map<String, Object> toBeanMethodMap = new HashMap<String, Object>();
    
    /***
     * <pre>
     * 功能：实现BEAN的属性对拷
     * 创建人：JokenWang
     * 创建时间：2014年12月16日 上午9:01:02
     * </pre>
     * 
     * @param fromBean
     *            待转换的源bean
     * @param toBeanName
     *            转换成目标bean的名称 形如：ItemSeries.class.getName()
     * @return 目标BEAN类
     * @version 1.0.0
     * @param <T>
     * @throws Exception
     */
    public static <T> T convertBean(Object fromBean, Class<T> toBeanClassName)
    {
        T toBean = null;
        try
        {
            toBean = getBeanInstance(toBeanClassName.getName());
            return convertBean(fromBean, toBean);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return toBean;
    }
    
    private static <T> T convertBean(Object fromBean, T toBean)
    {
        BeanUtil.getBeanUtilBean().getTypeConverterManager().register(String.class, new StringConverter());
        BeanCopy.beans(fromBean, toBean).copy();
        return toBean;
    }
    
    public static Method getDeclaredMethod(Object object, String methodName, Class<?>... parameterTypes)
    {
        Method method = null;
        for (Class<?> clazz = object.getClass(); clazz != Object.class; clazz = clazz.getSuperclass())
        {
            try
            {
                method = clazz.getDeclaredMethod(methodName, parameterTypes);
                return method;
            }
            catch (Exception e)
            {
            }
        }
        return null;
    }
    
    @SuppressWarnings("unchecked")
    public static <T> T getBeanInstance(String clazzName) throws InstantiationException, IllegalAccessException, ClassNotFoundException
    {
        return (T) Class.forName(clazzName).newInstance();
    }
    
    public static Map<String, Object> toBeanMethodMap(String toBean) throws InstantiationException, IllegalAccessException, ClassNotFoundException
    {
        Class<?> toBeanClazz = getBeanInstance(toBean).getClass();
        Method[] toBeanMethods = toBeanClazz.getDeclaredMethods();
        if (!toBeanClazz.isInstance(Object.class))// 非超类Object
        {
            for (Method method : toBeanMethods)
            {
                String methodName = method.getName();
                toBeanMethodMap.put(methodName, method);
            }
            
            Class<?> toBeanSuperclazz = toBeanClazz.getSuperclass();// 获取父类
            toBeanMethodMap(toBeanSuperclazz.getName());
        }
        
        return toBeanMethodMap;
    }
    
    /***
     * <pre>
     * 功能：将传递来的对象属性值映射到MAP
     * 创建人：JokenWang
     * 创建时间：2014年12月16日 下午10:36:00
     * </pre>
     * 
     * @param
     * @return
     * @version 1.0.0
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> toMap(Object object)
    {
        Map<String, Object> map = new HashMap<String, Object>();
        
        if (object == null)
        {
            return map;
        }
        
        BeanMap beanMap = new BeanMap(object);
        Iterator<String> it = beanMap.keyIterator();
        while (it.hasNext())
        {
            String name = it.next();
            Object value = beanMap.get(name);
            // 转换时会将类名也转换成属性，此处去掉
            if (value != null && !name.equals("class"))
            {
                map.put(name, value);
            }
        }
        
        return map;
    }
    
    /***
     * <pre>
     * 功能：该方法将给定的所有对象参数列表转换合并生成一个Map，对于同名属性，依次由后面替换前面的对象属性
     * 创建人：JokenWang
     * 创建时间：2014年12月16日 下午10:41:31
     * </pre>
     * 
     * @param
     * @return
     * @version 1.0.0
     */
    public static Map<String, Object> toMap(Object... objs)
    {
        Map<String, Object> map = new HashMap<String, Object>();
        for (Object object : objs)
        {
            if (object != null)
            {
                map.putAll(toMap(object));
            }
        }
        return map;
    }
}
